package com.org.oracle.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.org.oracle.mapper.UserDailyStudyTimeMapper;
import com.org.oracle.mapper.UserQuestionProgressMapper;
import com.org.oracle.mysql.dto.AnswerDetailDTO;
import com.org.oracle.mysql.dto.UserAnswerSubmitDTO;
import com.org.oracle.mysql.entity.*;
import com.org.oracle.mapper.UserCommitResultsMapper;
import com.org.oracle.mysql.vo.ChapterProgressVo;
import com.org.oracle.mysql.vo.SubjectStudyTimeVo;
import com.org.oracle.mysql.vo.UserCommitResultVo;
import com.org.oracle.result.Result;
import com.org.oracle.service.*;
import com.org.oracle.util.BeanCopyUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * (UserCommitResults)表服务实现类
 *
 * @author luo
 * @since 2024-12-16 20:37:19
 */
@EnableScheduling
@Slf4j
@Service("userCommitResultsService")
public class UserCommitResultsServiceImpl extends ServiceImpl<UserCommitResultsMapper, UserCommitResult> implements UserCommitResultsService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private QuestionsService questionsService;
    @Resource
    private UserAnswerDetailsService userAnswerDetailsService;
    @Resource
    private UserCommitResultsMapper userCommitResultsMapper;
    @Resource
    private UserDailyStudyTimeMapper userDailyStudyTimeMapper;
    @Resource
    private UserQuestionProgressMapper userQuestionProgressMapper;
    @Resource
    private QuestionChaptersService questionChaptersService;
    @Resource
    private SubjectsService subjectService;
    /**
     * 用户正常上传答题记录
     *
     * @param uid
     * @param submitDTO 包含了每一道题的id，用户答案，开始和结束时间戳
     * @return userCommitResultVo 用户的正确率、答题用时等等字段
     */
    @Override
    @Transactional // 开启事务
    public Result userUpLoadAnswer(String uid, UserAnswerSubmitDTO submitDTO) {
        //获取用户的作答题目id
        List<Long> questionIds = submitDTO.getAnswerDetails().stream()
                .map(AnswerDetailDTO::getQuestionId)
                .toList();
        //获取正确答案（提高性能，一起获取）
        Map<Long, String> userAnswers = questionsService.getAnswersByIds(questionIds);
        // 设置对象的属性
        UserCommitResult userCommitResult = new UserCommitResult();
        userCommitResult.setUid(uid);


        // 解析出用户的作答情况
        List<AnswerDetailDTO> answerDetails = submitDTO.getAnswerDetails();
        int totalCount = answerDetails.size();
        userCommitResult.setTotalCount(totalCount);
        //这里是为了消减前端的subjectId而做的
        //TODO 取消subjectId,或者是chapterId
        AnswerDetailDTO detailDTO = answerDetails.get(0);
        Long questionId = detailDTO.getQuestionId();
        Questions question = questionsService.getById(questionId);
        userCommitResult.setSubjectId(question.getSubjectId());
        userCommitResult.setChapterId(submitDTO.getChapterId());

        int correctCount = 0;
        float totalScore = 0f;
        List<UserAnswerDetail> userAnswerDetails = new ArrayList<>();
        // 获取当前时间，使用更精确的方式获取当前日期时间，指定系统默认时区（上海时区），避免潜在的时区等问题影响日期准确性
        LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
        Date currentDate = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());

        // 累计本次答题正常用时（不包含暂存用时，先初始化为0）
        long normalTotalStudyTime = 0;
        // 累计本次答题的暂存总用时（从 Redis 获取并累加，先初始化为0）
        long cachedTotalStudyTime = 0;

        // 先处理暂存题目相关逻辑
        // 查询暂存题目（包括当天暂存和累计暂存）并统计时长等逻辑
        QueryWrapper<UserAnswerDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", uid).eq("is_temporary", 1);
        List<UserAnswerDetail> temporaryAnswerDetails = userAnswerDetailsService.list(queryWrapper);

        // 处理暂存题目相关逻辑，仅获取暂存总用时并删除对应的Redis记录
        Set<String> cachedQuestionTimeKeys = redisTemplate.keys("temporary_question_time:" + uid + ":*");
        if (cachedQuestionTimeKeys!= null &&!cachedQuestionTimeKeys.isEmpty()) {
            for (String key : cachedQuestionTimeKeys) {
                Object cachedObj = redisTemplate.opsForValue().get(key);
                Long cachedQuestionTime = 0L;
                if (cachedObj instanceof Number) {
                    cachedQuestionTime = ((Number) cachedObj).longValue();
                }
                cachedTotalStudyTime += cachedQuestionTime;
                redisTemplate.delete(key);
            }
        }

        // 处理正常答题题目逻辑，统计正常答题用时以及构建正式提交的答题详情对象
        for (AnswerDetailDTO answerDetailDTO : answerDetails) {
            UserAnswerDetail userAnswerDetail = buildUserAnswerDetail(uid,submitDTO, answerDetailDTO, userAnswers, currentDate);
            userAnswerDetails.add(userAnswerDetail);

            totalScore += userAnswerDetail.getScore();
            if (userAnswerDetail.getIsCorrect() == 1) {
                correctCount++;
            }

            long normalQuestionTime = answerDetailDTO.getEndTimestamp() - answerDetailDTO.getStartTimestamp();
            normalTotalStudyTime += normalQuestionTime;
        }
        // 先批量保存或更新正常提交的答题详情记录（不管是新记录还是已有记录更新）
        userAnswerDetailsService.saveOrUpdateBatch(userAnswerDetails);

        // 处理暂存题目转为正式提交的答题详情对象（更新或替换原暂存记录）
        for (UserAnswerDetail temporaryDetail : temporaryAnswerDetails) {
            UserAnswerDetail userAnswerDetail = buildUserAnswerDetail(uid, submitDTO,
                    AnswerDetailDTO.builder()
                            .questionId(temporaryDetail.getQuestionId())
                            .userAnswer(temporaryDetail.getUserAnswer())
                            .startTimestamp(temporaryDetail.getStartTimestamp())
                            .endTimestamp(temporaryDetail.getEndTimestamp())
                            .build(),
                    userAnswers,
                    currentDate);
            // 根据题目ID和用户ID以及is_temporary字段查找对应的暂存记录
            QueryWrapper<UserAnswerDetail> updateWrapper = new QueryWrapper<>();
            updateWrapper.eq("uid", uid).eq("question_id", temporaryDetail.getQuestionId()).eq("is_temporary",1);
            UserAnswerDetail existingRecord = userAnswerDetailsService.getOne(updateWrapper);
            if (existingRecord!= null) {
                // 如果已存在记录（可能之前有暂存等情况），更新对应记录为正式提交的答题详情信息
                userAnswerDetail.setId(existingRecord.getId());
                userAnswerDetailsService.updateById(userAnswerDetail);
            } else {
                // 如果不存在记录，直接保存正式提交的答题详情
                userAnswerDetailsService.save(userAnswerDetail);
            }
        }
        // 计算答题正确率
        float accuracy = totalCount > 0 ? (float) correctCount / totalCount * 100 : 0f;
        userCommitResult.setTotalScore(totalScore);
        userCommitResult.setCorrectCount(correctCount);
        userCommitResult.setAccuracy(accuracy);
        userCommitResult.setStatus("已完成");
        userCommitResult.setSubmittedAt(currentDate);
        //设置本次答题的总刷题时长到UserCommitResult中包含正常答题用时和暂存累加的用时）
        userCommitResult.setTotalStudyTime(normalTotalStudyTime + cachedTotalStudyTime);
        userCommitResult.setCreatedAt(currentDate);
        userCommitResult.setUpdatedAt(currentDate);

        // 保存UserCommitResult
        userCommitResultsMapper.insert(userCommitResult);
        Long userCommitResultId = userCommitResult.getId();

        // 设置答题详情的userCommitResultId
        userAnswerDetails.forEach(userAnswerDetail -> userAnswerDetail.setUserCommitResultId(userCommitResultId));

        // 批量插入（更新）用户答题详情
        userAnswerDetailsService.updateBatchById(userAnswerDetails);
        // 将总刷题时长（毫秒）转换为分钟，赋值给UserCommitResultVo的studyTimeInMinutes字段
        float studyTimeInMinutes = (float) (normalTotalStudyTime + cachedTotalStudyTime) / (1000 * 60);
        UserCommitResultVo userCommitResultVo = BeanCopyUtils.copyBean(userCommitResult, UserCommitResultVo.class);
        userCommitResultVo.setStudyTimeInMinutes(studyTimeInMinutes);
        // 更新或插入用户每日刷题时间记录
        updateOrInsertDailyStudyTime(uid, currentDate, normalTotalStudyTime + cachedTotalStudyTime);
        // 更新user_question_progress表中对应题目的完成状态为已完成
        updateQuestionProgressAsCompleted(uid, answerDetails.stream().map(AnswerDetailDTO::getQuestionId).collect(Collectors.toList()));
        // 清理暂存相关数据（这里主要是将暂存题目对应的记录标记为已提交状态）
        for (UserAnswerDetail detail : temporaryAnswerDetails) {
            detail.setIsTemporary(0);
            detail.setTemporaryType(0);
            userAnswerDetailsService.updateById(detail);
        }
        // 返回相应结果
        return Result.ok(userCommitResultVo);
    }

    @Override
    @Transactional // 开启事务
    public Result userTemporarySaveAnswer(String uid, UserAnswerSubmitDTO submitDTO) {
        // 获取用户的作答题目id
        List<Long> questionIds = submitDTO.getAnswerDetails().stream()
                .map(AnswerDetailDTO::getQuestionId)
                .toList();
        Map<Long, String> userAnswers = questionsService.getAnswersByIds(questionIds);

        // 解析出用户的作答情况
        List<AnswerDetailDTO> answerDetails = submitDTO.getAnswerDetails();

        List<UserAnswerDetail> userAnswerDetails = new ArrayList<>();
        Date now = new Date();

        for (AnswerDetailDTO answerDetailDTO : answerDetails) {
            UserAnswerDetail userAnswerDetail = new UserAnswerDetail();
            userAnswerDetail.setUid(uid);
            userAnswerDetail.setQuestionId(answerDetailDTO.getQuestionId());
            userAnswerDetail.setUserAnswer(answerDetailDTO.getUserAnswer());

            // 设置为暂存答案
            userAnswerDetail.setIsTemporary(1);

            // 根据当前时间判断暂存类型（当天暂存或累计暂存）
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(now);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            Date startOfDay = calendar.getTime();
            int temporaryType = now.getTime() >= startOfDay.getTime()? 1 : 2;
            userAnswerDetail.setTemporaryType(temporaryType);

            // 设置开始做该题的时间戳
            userAnswerDetail.setStartTimestamp(answerDetailDTO.getStartTimestamp());

            // 设置做完该题的时间戳
            userAnswerDetail.setEndTimestamp(answerDetailDTO.getEndTimestamp());

            // 获取题目正确答案（此处仅用于可能的前端展示等需求，暂存时不进行对错判断等操作）
            String correctAnswer = userAnswers.get(answerDetailDTO.getQuestionId());

            // 设置其他通用属性，如时间等
            userAnswerDetail.setCreatedAt(now);
            userAnswerDetail.setUpdatedAt(now);

            // 计算本题暂存用时（毫秒），并累加到缓存中对应题目的用时记录
            long questionTime = userAnswerDetail.getEndTimestamp() - userAnswerDetail.getStartTimestamp();

            // 将本题暂存用时累加到 Redis 中对应题目的累计用时记录上（以题目 ID 作为 Redis 的 key）
            String questionIdStr = String.valueOf(answerDetailDTO.getQuestionId());
            String cacheKey = "temporary_question_time:" + uid + ":" + questionIdStr;
            Object cachedObj = redisTemplate.opsForValue().get(cacheKey);
            Long cachedTime = 0L;
            if (cachedObj instanceof Number) {
                cachedTime = ((Number) cachedObj).longValue();
            }
            redisTemplate.opsForValue().set(cacheKey, cachedTime + questionTime);

            // 如果是当天暂存，在Redis中记录当天暂存题目数（方便后续统计当天刷题数等情况）
            if (temporaryType == 1) {
                String todayTemporaryCountKey = "today_temporary_count:" + uid;
                Object countObj = redisTemplate.opsForValue().get(todayTemporaryCountKey);
                Long todayTemporaryCount = 0L;
                if (countObj instanceof Number) {
                    todayTemporaryCount = ((Number) countObj).longValue();
                }
                redisTemplate.opsForValue().set(todayTemporaryCountKey, todayTemporaryCount + 1);
            }
            userAnswerDetails.add(userAnswerDetail);
        }

        // 批量插入或更新用户答题详情（暂存答案逻辑，需要根据is_temporary字段判断处理）
        temporarySaveBatch(userAnswerDetails);

        // 更新user_question_progress表中对应题目的完成状态为未完成（因为只是暂存，不算完成题目）
        updateQuestionProgressAsUncompleted(uid, answerDetails.stream().map(AnswerDetailDTO::getQuestionId).collect(Collectors.toList()));

        return Result.ok("答案暂存成功");
    }

    @Override
    public boolean isChapterCompleted(String uid, String chapterId) {
        // 获取章节总题目数量
        int totalQuestionCount = questionsService.getQuestionNumByChapterId(chapterId);
        if (totalQuestionCount == 0) {
            return true;
        }
        QueryWrapper<UserQuestionProgress> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", uid).eq("chapter_id", chapterId).eq("is_completed", 1);
        int completedCount = Math.toIntExact(userQuestionProgressMapper.selectCount(queryWrapper));

        return completedCount == totalQuestionCount;
    }

    @Override
    public Date getLastSubmitOrTemporaryTime(String uid, String chapterId) {
        QueryWrapper<UserCommitResult> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", uid).eq("chapter_id", chapterId);
        queryWrapper.orderByDesc("submitted_at");
        queryWrapper.last("LIMIT 1");
        UserCommitResult lastResult = userCommitResultsMapper.selectOne(queryWrapper);
        return lastResult!= null? lastResult.getSubmittedAt() : null;
    }

    @Override
    public Long getChapterTotalStudyTime(String uid, String chapterId) {
        // 先获取正常答题累计用时
        QueryWrapper<UserCommitResult> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", uid).eq("chapter_id", chapterId);
        List<UserCommitResult> results = userCommitResultsMapper.selectList(queryWrapper);
        long normalTotalTime = 0;
        for (UserCommitResult result : results) {
            normalTotalTime += result.getTotalStudyTime();
        }

        // 再获取暂存题目累计用时（从 Redis 中获取并累加）
        Set<String> cachedQuestionTimeKeys = redisTemplate.keys("temporary_question_time:" + uid + ":*");
        long cachedTotalTime = 0;
        if (cachedQuestionTimeKeys!= null &&!cachedQuestionTimeKeys.isEmpty()) {
            for (String key : cachedQuestionTimeKeys) {
                Object cachedObj = redisTemplate.opsForValue().get(key);
                Long cachedQuestionTime = 0L;
                if (cachedObj instanceof Number) {
                    cachedQuestionTime = ((Number) cachedObj).longValue();
                }
                cachedTotalTime += cachedQuestionTime;
            }
        }
        //累加时间，毫秒转分钟
        return (normalTotalTime + cachedTotalTime) / (1000 * 60);
    }

    @Override
    public List<ChapterProgressVo> getChapterProgressBySubjectId(String uid, String subjectId) {
        // 先获取该科目下的所有章节信息
        LambdaQueryWrapper<QuestionChapters> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(QuestionChapters::getSubjectId, subjectId);
        List<QuestionChapters> questionChapters = questionChaptersService.list(queryWrapper);
        //初始化
        List<ChapterProgressVo> resultList = new ArrayList<>();

        for (QuestionChapters chapter : questionChapters) {
            boolean isCompleted = isChapterCompleted(uid,chapter.getId().toString());
            Date lastSubmitOrTemporaryTime = getLastSubmitOrTemporaryTime(uid, chapter.getId().toString());
            Long totalStudyTime = getChapterTotalStudyTime(uid, chapter.getId().toString());
            Integer questionNum = questionsService.getQuestionNumByChapterId(String.valueOf(chapter.getId()));
            //设置新的属性
            ChapterProgressVo vo = new ChapterProgressVo(chapter.getId().toString(),chapter.getName(),questionNum,isCompleted,lastSubmitOrTemporaryTime,totalStudyTime);
            resultList.add(vo);
        }
        return resultList;
    }

    /**
     * 获取用户当天每一个科目的刷题时间，即408的4本书的刷题时间
     * @param uid 用户uid
     * @return 当天各科刷题时间
     */
    @Override
    public List<SubjectStudyTimeVo> getSubjectStudyTimeToday(String uid) {
        // 先获取所有科目信息
        List<Subjects> allSubjects = subjectService.getAllSubjects();

        // 用于累计每个科目的学习时间（以科目ID为键），初始化为0
        Map<String, Long> subjectTimeMap = allSubjects.stream()
                .collect(Collectors.toMap(subject -> subject.getId().toString(), s -> 0L));

        // 获取当天日期（使用系统默认时区）
        LocalDate today = LocalDate.now(ZoneId.systemDefault());
        LocalDateTime startOfDay = today.atStartOfDay();
        LocalDateTime endOfDay = LocalDateTime.of(today, LocalTime.MAX);
        java.sql.Timestamp startTimestamp = java.sql.Timestamp.valueOf(startOfDay);
        java.sql.Timestamp endTimestamp = java.sql.Timestamp.valueOf(endOfDay);

        // 查询当天有答题记录的 UserAnswerDetail（正常提交和暂存的都算，因为都涉及学习时间）
        QueryWrapper<UserAnswerDetail> userAnswerDetailQueryWrapper = new QueryWrapper<>();
        userAnswerDetailQueryWrapper.eq("uid", uid)
                .ge("created_at", startTimestamp)
                .le("created_at", endTimestamp);
        List<UserAnswerDetail> userAnswerDetails = userAnswerDetailsService.list(userAnswerDetailQueryWrapper);

        // 遍历当天所有答题记录，获取对应的题目信息，累加每个科目的学习时间
        for (UserAnswerDetail userAnswerDetail : userAnswerDetails) {
            Long questionId = userAnswerDetail.getQuestionId();
            Questions question = questionsService.getById(questionId);
            String subjectId = question.getSubjectId();
            long questionStudyTime = userAnswerDetail.getEndTimestamp() - userAnswerDetail.getStartTimestamp();

            subjectTimeMap.put(subjectId, subjectTimeMap.getOrDefault(subjectId, 0L) + questionStudyTime);
        }

        // 再处理暂存题目对应的学习时间（从Redis中获取并累加,暂存题目时间记录在Redis中）
        Set<String> cachedQuestionTimeKeys = redisTemplate.keys("temporary_question_time:" + uid + ":*");
        if (cachedQuestionTimeKeys!= null &&!cachedQuestionTimeKeys.isEmpty()) {
            for (String key : cachedQuestionTimeKeys) {
                String[] parts = key.split(":");
                String questionIdStr = parts[2];
                Long questionId = Long.parseLong(questionIdStr);
                Questions question = questionsService.getById(questionId);
                String subjectId = question.getSubjectId();

                Object cachedObj = redisTemplate.opsForValue().get(key);
                Long cachedQuestionTime = 0L;
                if (cachedObj instanceof Number) {
                    cachedQuestionTime = ((Number) cachedObj).longValue();
                }

                subjectTimeMap.put(subjectId, subjectTimeMap.getOrDefault(subjectId, 0L) + cachedQuestionTime);
            }
        }

        // 将毫秒单位的时间转换为分钟，并封装成 SubjectStudyTimeVo 对象列表
        List<SubjectStudyTimeVo> resultList = new ArrayList<>();
        for (Subjects subject : allSubjects) {
            long studyTimeInMinutes = subjectTimeMap.getOrDefault(subject.getId().toString(), 0L) / (1000 * 60);
            resultList.add(new SubjectStudyTimeVo(subject.getId().toString(), subject.getName(), studyTimeInMinutes));
        }

        return resultList;
    }

    @Override
    public Float getSubjectProgressByUid(String uid) {
        // 获取所有章节
        List<QuestionChapters> chaptersList = questionChaptersService.list();
        int total = chaptersList.size();

        // 如果没有章节，直接返回0.0f，避免除零错误
        if (total == 0) {
            return 0.0f;
        }

        // 统计已完成的章节数
        long completedCount = chaptersList.stream()
                .filter(chapter -> isChapterCompleted(uid, String.valueOf(chapter.getId())))
                .count();

        // 计算并返回完成率
        return (float) completedCount / total;
    }


    /**
     * 根据用户ID、日期以及本次答题总时长，更新或插入用户每日刷题时间记录
     *
     * @param uid 用户ID
     * @param date 当前答题日期
     * @param studyTime 本次答题总时长（毫秒）
     */
    private void updateOrInsertDailyStudyTime(String uid, Date date, long studyTime) {
        // 将传入的Date类型转换为LocalDate类型，依据系统默认时区进行转换，确保获取准确的日期部分
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        java.sql.Date sqlDate = java.sql.Date.valueOf(localDate);

        try {
            // 查询用户是否已有当天的记录
            QueryWrapper<UserDailyStudyTime> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("uid", uid).eq("date", sqlDate);
            UserDailyStudyTime record = userDailyStudyTimeMapper.selectOne(queryWrapper);

            if (record!= null) {
                // 如果记录存在，累加答题时间
                record.setTotalStudyTime(record.getTotalStudyTime() + studyTime);
                userDailyStudyTimeMapper.updateById(record);
            } else {
                // 如果记录不存在，插入新记录
                UserDailyStudyTime newRecord = new UserDailyStudyTime();
                newRecord.setUid(uid);
                newRecord.setDate(sqlDate);
                newRecord.setTotalStudyTime(studyTime);
                userDailyStudyTimeMapper.insert(newRecord);
            }
        } catch (Exception e) {
            System.out.println("Exception caught: " + e.getMessage());  // 输出异常信息
            e.printStackTrace();
        }
    }

    // 提取构建UserAnswerDetail对象的方法，使代码更清晰
    private UserAnswerDetail buildUserAnswerDetail(String uid, UserAnswerSubmitDTO submitDTO, AnswerDetailDTO answerDetailDTO,
                                                   Map<Long, String> userAnswers, Date currentDate) {
        UserAnswerDetail userAnswerDetail = new UserAnswerDetail();
        userAnswerDetail.setUid(uid);
        userAnswerDetail.setQuestionId(answerDetailDTO.getQuestionId());
        userAnswerDetail.setUserAnswer(answerDetailDTO.getUserAnswer());
        userAnswerDetail.setIsTemporary(0);

        // 获取题目正确答案并判断是否正确
        String correctAnswer = userAnswers.get(answerDetailDTO.getQuestionId());
        boolean isCorrect = correctAnswer!= null && correctAnswer.equals(userAnswerDetail.getUserAnswer());
        userAnswerDetail.setIsCorrect(isCorrect? 1 : 0);

        // 设置每题分数
        float score = isCorrect? 1f : 0f;
        userAnswerDetail.setScore(score);

        // 设置每道题的开始时间戳和结束时间戳
        userAnswerDetail.setStartTimestamp(answerDetailDTO.getStartTimestamp());
        userAnswerDetail.setEndTimestamp(answerDetailDTO.getEndTimestamp());

        // 设置创建时间和更新时间为传入的当前时间
        userAnswerDetail.setCreatedAt(currentDate);
        userAnswerDetail.setUpdatedAt(currentDate);

        return userAnswerDetail;
    }
    /**
     * 批量插入或更新用户答题详情（针对暂存答案情况），在user_answer_details表中插入或更新数据，根据是否已存在记录以及is_temporary字段进行处理，这样已有记录的话，就不会重复插入了！
     *
     * @param userAnswerDetails 包含用户暂存答案信息的列表
     */
    private void temporarySaveBatch(List<UserAnswerDetail> userAnswerDetails) {
        for (UserAnswerDetail userAnswerDetail : userAnswerDetails) {
            QueryWrapper<UserAnswerDetail> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("uid", userAnswerDetail.getUid()).eq("question_id", userAnswerDetail.getQuestionId()).eq("is_temporary", 1);
            UserAnswerDetail existingRecord = userAnswerDetailsService.getOne(queryWrapper);
            if (existingRecord!= null) {
                // 如果已存在暂存记录，更新答案内容等信息
                existingRecord.setUserAnswer(userAnswerDetail.getUserAnswer());
                existingRecord.setUpdatedAt(new Date());
                userAnswerDetailsService.updateById(existingRecord);
            } else {
                // 设置userCommitResultId为约定的默认值（-1，表示暂存答案）
                userAnswerDetail.setUserCommitResultId(-1L);
                userAnswerDetailsService.save(userAnswerDetail);
            }
        }
    }
    /**
     * 将指定用户、题目列表在user_question_progress表中的完成状态更新为未完成
     *
     * @param uid 用户ID
     * @param questionIds 题目ID列表
     */
    private void updateQuestionProgressAsUncompleted(String uid, List<Long> questionIds) {
        for (Long questionId : questionIds) {
            QueryWrapper<UserQuestionProgress> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("uid", uid).eq("question_id", questionId);
            UserQuestionProgress progress = userQuestionProgressMapper.selectOne(queryWrapper);
            if (progress == null) {
                // 如果不存在记录，则插入新记录
                UserQuestionProgress newProgress = new UserQuestionProgress();
                newProgress.setUid(uid);
                newProgress.setQuestionId(String.valueOf(questionId));
                // 同样假设能获取到正确的subjectId和chapterId并传入
                Questions question = questionsService.getById(questionId);
                newProgress.setSubjectId(question.getSubjectId());
                newProgress.setChapterId(question.getChapterId());
                newProgress.setIsCompleted(0);
                LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
                Date currentDate = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
                newProgress.setCreatedAt(currentDate);
                newProgress.setUpdatedAt(currentDate);
                userQuestionProgressMapper.insert(newProgress);
            } else {
                // 如果已存在记录，更新完成状态为未完成
                progress.setIsCompleted(0);
                userQuestionProgressMapper.updateById(progress);
            }
        }
    }

    /**
     * 更新用户完成状态
     * @param uid
     * @param questionIds
     */
    private void updateQuestionProgressAsCompleted(String uid, List<Long> questionIds) {
        for (Long questionId : questionIds) {
            QueryWrapper<UserQuestionProgress> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("uid", uid).eq("question_id", questionId);
            UserQuestionProgress progress = userQuestionProgressMapper.selectOne(queryWrapper);
            if (progress == null) {
                // 如果不存在记录，则插入新记录
                UserQuestionProgress newProgress = new UserQuestionProgress();
                newProgress.setUid(uid);
                newProgress.setQuestionId(String.valueOf(questionId));
                // 这里假设你在调用此方法时能获取到对应的subjectId和chapterId，需要根据实际情况传入正确的值
                Questions question = questionsService.getById(questionId);
                newProgress.setSubjectId(question.getSubjectId());
                newProgress.setChapterId(question.getChapterId());
                newProgress.setIsCompleted(1);
                // 设置当前时间
                LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
                Date currentDate = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
                newProgress.setCreatedAt(currentDate);
                newProgress.setUpdatedAt(currentDate);
                userQuestionProgressMapper.insert(newProgress);
            } else {
                // 如果已存在记录，更新完成状态为已完成
                progress.setIsCompleted(1);
                userQuestionProgressMapper.updateById(progress);
            }
        }
    }
    // 每天12点执行删除today_temporary_count相关键值对的任务，使用Redis管道提升删除效率
    @Scheduled(cron = "0 0 12 * * *")
    public void clearTodayTemporaryCount() {
        RedisCallback<List<Object>> deleteCallback = (RedisConnection connection) -> {
            connection.openPipeline();
            Set<String> keysToDelete = redisTemplate.keys("today_temporary_count:*");
            if (keysToDelete!= null &&!keysToDelete.isEmpty()) {
                for (String key : keysToDelete) {
                    connection.keyCommands().del(key.getBytes());
                }
            }
            return connection.closePipeline();
        };
        try {
            List<Object> results = redisTemplate.execute(deleteCallback);
            // TODO 判断是否删除成功
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

